package com.tang.provider;

import com.tang.service.MongoDbService;
import com.tang.util.MongoDBUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by tangyifei on 2018/7/6.
 */
@Api(value = "micro-service-core-nosql-mongo", tags = {"micro-service-core-nosql-mongo"})
@Controller
@RefreshScope
public class MongoProvider {

    private static final Logger logger = LogManager.getLogger(MongoProvider.class);

    @Resource
    private MongoDbService mongoDb;

    @Resource
    private MongoDBUtil document;

    /**
     * 插入到mongo中（批量插入和单个插入）
     *
     * @param collection
     * @param model
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "插入文档（批量插入文档和单个插入文档）", httpMethod = "POST", notes = "插入文档（批量插入文档和单个插入文档）")
    @PostMapping("/mongodb/{collection}/{flag}")
    public ResponseEntity<?> add(
            @PathVariable("collection") @ApiParam(required = true, name = "collection", value = "访问的集合名称") String collection,
            @PathVariable("flag") @ApiParam(required = true, name = "flag", value = "1表示单个插入 2表示批量插入") Integer flag,
            @RequestBody @ApiParam(value = "json格式", name = "保存的json格式对象", required = true) String model)
            throws Exception {
        if (flag == 2) { // 批量插入数据到mongo中
            mongoDb.insertList(document.jsonToDocumentList(model), collection);
        } else if (flag == 1) { // 单个插入数据到mongo中
            mongoDb.insert(document.jsonToDocument(model), collection);
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 查询相关的文档（精确查询和模糊查询）
     *
     * @param searchKey
     * @param flag
     * @param page
     * @param pageSize
     * @param collection
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "查询相关的文档（精确查询和模糊查询）", httpMethod = "POST", notes = "查询相关的文档（精确查询和模糊查询）")
    @PostMapping("/mongodb/{collection}")
    public ResponseEntity<List<Document>> list(
            @RequestParam(value = "flag", required = false) @ApiParam(defaultValue = "0", example = "0", required = false, name = "flag", value = "默认值给0 1表示精确查询   2表示模糊查询") Integer flag,
            @RequestParam(value = "page", required = false) @ApiParam(defaultValue = "0", example = "0", required = false, name = "page", value = "默认值给0 当前页") Integer page,
            @RequestParam(value = "pageSize", required = false) @ApiParam(defaultValue = "0", example = "0", required = false, name = "pageSize", value = "默认值给0 每页的大小") Integer pageSize,
            @PathVariable("collection") @ApiParam(required = true, name = "collection", value = "访问的集合名称") String collection,
            @RequestBody(required = false) @ApiParam(value = "json格式", name = "封装成json格式的查询参数", required = false) String searchKey)
            throws Exception {
        if (!StringUtils.isEmpty(searchKey) && !"{}".equals(searchKey)) {
            ResponseEntity<List<Document>> result = null;
            if (1 == flag) { // 精确查询
                // 将json格式的参数转化为document
                Document doc = document.jsonToDocument(searchKey);
                result = new ResponseEntity<>(mongoDb.findBy(doc, collection,
                        page, pageSize), HttpStatus.OK);
            } else if (2 == flag) { // 模糊查询
                Document doc = document.jsonToDocumentLike(searchKey);
                result = new ResponseEntity<>(mongoDb.findBy(doc, collection,
                        page, pageSize), HttpStatus.OK);
            }
            return result;

        } else {
            return new ResponseEntity<>(mongoDb.findAll(collection, page,
                    pageSize), HttpStatus.OK);
        }
    }

    /**
     * 更新mongo中的文档（批量更新和单个更新）
     *
     * @param collection
     * @param model
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "更新mongo中的文档（批量更新文档和单个更新文档）", httpMethod = "PUT", notes = "更新mongo中的文档（批量更新文档和单个更新文档）")
    @PutMapping("/mongodb/{collection}/{flag}")
    public ResponseEntity<?> update(
            @PathVariable("collection") @ApiParam(required = true, name = "collection", value = "访问的集合名称") String collection,
            @PathVariable("flag") @ApiParam(required = true, name = "flag", value = "1表示单个更新  2表示批量更新") Integer flag,
            @RequestBody @ApiParam(value = "json格式的入参，形式为{'_id':'12121313','userName':'唐义斐'}", name = "保存的json格式的参数，需要传入_id，注意必须是_id形式", required = true) String model)
            throws Exception {
        if (flag == 2) { // 批量更新数据到mongo中
            mongoDb.updateMany(model, collection);
        } else if (flag == 1) { // 单个更新数据到mongo中
            mongoDb.updateOne(document.jsonToDocumentForUpdate(model),
                    collection);
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 删除mongo中的文档（批量删除文档和单个删除文档）
     *
     * @param collection
     * @param model
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "删除mongo中的文档（批量删除文档和单个删除文档）", httpMethod = "DELETE", notes = "删除mongo中的文档（批量删除文档和单个删除文档）")
    @DeleteMapping("/mongodb/{collection}/{flag}")
    public ResponseEntity<?> delete(
            @PathVariable("collection") @ApiParam(required = true, name = "collection", value = "访问的集合名称") String collection,
            @PathVariable("flag") @ApiParam(required = true, name = "flag", value = "1表示单个删除  2表示批量删除") Integer flag,
            @RequestBody @ApiParam(value = "json格式的入参，形式为{'_id':'12121313'}即可，删除时，不需要其他的参数，只需要_id", name = "保存的json格式的参数，必须填写，需要传入_id，注意必须是_id形式", required = true) String model)
            throws Exception {
        if (flag == 2) { // 批量删除数据
            mongoDb.deleteMany(model, collection);
        } else if (flag == 1) { // 单个删除数据
            mongoDb.deleteOne(document.jsonToDocumentForDelete(model),
                    collection);
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 删除相关的的集合
     *
     * @param collection
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "删除相关的的集合", httpMethod = "DELETE", notes = "删除相关的的集合")
    @DeleteMapping("/mongodb/{collection}")
    public ResponseEntity<?> deleteCollection(
            @PathVariable("collection") @ApiParam(required = true, name = "collection", value = "访问的集合名称") String collection)
            throws Exception {
        mongoDb.deleteConllection(collection);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 分布式配置刷新
     */
    @Value("${neo.hello}")
    private String hello;

    @ApiOperation(value = "分布式配置刷新", httpMethod = "GET", notes = "分布式配置刷新")
    @GetMapping("/user/hello")
    public ResponseEntity<?> hello() throws Exception {
        String hello = "获取的hello的值为" + this.hello;
        return new ResponseEntity<>(hello, HttpStatus.OK);
    }

}
